/*
    SUSAN® - Sole of Unix Save ANything

   

   
*/
/*
 * Marco van Wieringen, August 2013.
 */
/**
 * @file
 * Circular buffer used for producer/consumer problem with pthread.
 */


#define QSIZE 10 /**< # of pointers in the queue */

class CircularBuffer {
  int size_ = 0;
  int next_in_ = 0;
  int next_out_ = 0;
  int capacity_ = 0;
  bool flush_ = 0;
  pthread_mutex_t lock_ = PTHREAD_MUTEX_INITIALIZER; /**< Lock the structure */
  pthread_cond_t notfull_ =
      PTHREAD_COND_INITIALIZER; /**< Full -> not full condition */
  pthread_cond_t notempty_ =
      PTHREAD_COND_INITIALIZER; /**< Empty -> not empty condition */
  void** data_ = nullptr;       /**< Circular buffer of pointers */

 public:
  CircularBuffer(int capacity = QSIZE);
  ~CircularBuffer();
  int init(int capacity);
  void destroy();
  int enqueue(void* data);
  void* dequeue();
  int NextSlot();
  int flush();
  bool full() { return size_ == capacity_; }
  bool empty() { return size_ == 0; }
  bool IsFlushing() { return flush_; }
  int capacity() const { return capacity_; }
};

/**
 * Constructor
 */
inline CircularBuffer::CircularBuffer(int capacity) { init(capacity); }

/**
 * Destructor
 */
inline CircularBuffer::~CircularBuffer() { destroy(); }
